﻿/*******************************************************************************
* Copyright (C) JuCheap
* 
* Author: JuCheap
* Create Date: 2019/11/21 15:50:39
* Description: <Description>
* 
* Revision History:
* Date         Author               Description
*
*********************************************************************************/

using JuCheap.Core.Infrastructure.Extentions;
using JuCheap.Core.Infrastructure.Utilities;
using JuCheap.Core.IService;
using JuCheap.Core.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Threading.Tasks;

namespace JuCheap.Core.Infrastructure.Web
{
    /// <summary>
    /// 访问记录
    /// </summary>
    public class VisitLogFilter : ActionFilterAttribute
    {
        private readonly ICurrentUserService _currentUserService;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly IServiceScopeFactory _serviceScopeFactory;
        private readonly ILogger<VisitLogFilter> _logger;

        /// <summary>
        /// ctor
        /// </summary>
        public VisitLogFilter(ICurrentUserService currentUserService, IHttpContextAccessor httpContextAccessor,
            IServiceScopeFactory serviceScopeFactory,
            ILogger<VisitLogFilter> logger)
        {
            _currentUserService = currentUserService;
            _httpContextAccessor = httpContextAccessor;
            _serviceScopeFactory = serviceScopeFactory;
            _logger = logger;
        }

        /// <summary>
        /// OnActionExecuting
        /// </summary>
        /// <param name="context"></param>
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var request = context.HttpContext.Request;
            var httpContext = _httpContextAccessor?.HttpContext;
            var ip = httpContext?.Request?.Headers["X-Forwarded-For"].ToString();
            if (ip.IsBlank())
            {
                ip = httpContext?.Connection?.RemoteIpAddress?.ToString();
            }
            var url = $"{request.Scheme}://{request.Host.Value}{request.Path.Value}";
            var user = _currentUserService.GetCurrentUser();
            var visitLog = new SysVisitLogDto()
            {
                IP = ip,
                Url = url,
                UserName = user.Name,
                LoginAccount = user.LoginName,
                CompanyId = user.CompanyId,
                CreateUserId = user.UserId
            };
            Task.Run(async () =>
            {
                await WriteVisitLogAsync(visitLog);
            });

            base.OnActionExecuting(context);
        }

        /// <summary>
        /// 记录访问日志
        /// </summary>
        /// <returns></returns>
        private async Task WriteVisitLogAsync(SysVisitLogDto visitLog)
        {
            try
            {
                using (var scope = _serviceScopeFactory.CreateScope())
                {
                    var service = scope.ServiceProvider.GetRequiredService<ISysVisitLogService>();
                    await service.InsertAsync(visitLog);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "访问记录写入出错");
            }
        }
    }
}
